
#include "Camera.hpp"
#include "OpenGL.hpp"

using namespace Typhoon;

Camera::Camera():
	FieldOfView(this),
	Aspect(this),
	Near(this),
	Far(this),
	Projection(this),
	ProjectionInverse(this)
{
	FieldOfView = 45;
	Aspect = 1;
	Near = 0.1f;
	Far = 1000.0f;
	
	Projection.Method += event_handler(this, &Typhoon::Camera::CalcProjectionMatrix);
	ProjectionInverse.Method += event_handler(this, &Typhoon::Camera::CalcProjectionInverseMatrix);

	FieldOfView.Changed += event_handler(this, &Typhoon::Camera::ProjectionPropertyChanged);
	Aspect.Changed += event_handler(this, &Typhoon::Camera::ProjectionPropertyChanged);
	Near.Changed += event_handler(this, &Typhoon::Camera::ProjectionPropertyChanged);
	Far.Changed += event_handler(this, &Typhoon::Camera::ProjectionPropertyChanged);
}

void Camera::ProjectionPropertyChanged(Camera* camera) {
	Projection.MakeDirty();
	ProjectionInverse.MakeDirty();
}

void Camera::CalcProjectionMatrix(DirtyProperty<Camera*, Matrix4x4>::EventData& event) {
	Matrix4x4& mat = *event.Value;
	mat.InitPerspective(FieldOfView, Aspect, Near, Far);
}

void Camera::CalcProjectionInverseMatrix(DirtyProperty<Camera*, Matrix4x4>::EventData& event) {
	Matrix4x4& mat = *event.Value;
	mat = Projection.GetValue()->Invert();
}